package com.pxst.bank.service.impl;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pxst.bank.constants.RedisContant;
import com.pxst.bank.entity.*;
import com.pxst.bank.mapper.*;
import com.pxst.bank.req.BankDetailReq;
import com.pxst.bank.req.BankDetailSearchReq;
import com.pxst.bank.req.BankSearchReq;
import com.pxst.bank.req.BankUpdateReq;
import com.pxst.bank.resp.*;
import com.pxst.bank.service.SysAvailableBankService;
import com.pxst.bank.service.SysBankCardService;
import com.pxst.constants.BankCardConstant;
import com.pxst.fo.sys.entity.FoOrderMainEntity;
import com.pxst.fo.sys.mapper.SysFoOrderMainMapper;
import com.pxst.internalReports.entity.SysVpnEntity;
import com.pxst.internalReports.mapper.SysVpnEntityMapper;
import com.pxst.internalReports.req.BankAccountListReq;
import com.pxst.internalReports.resp.AccountListResp;
import com.pxst.internalReports.resp.BankAccountListResp;
import com.pxst.req.BasePageRsp;
import com.pxst.resp.ApiResp;
import com.pxst.resp.PageResp;
import com.pxst.sys.entity.SysDabTokenCard;
import com.pxst.sys.mapper.SysDabTokenCardMapper;
import com.pxst.sys.service.SysConfigService;
import com.pxst.utils.RedisUtils;
import com.pxst.utils.SecurityFrameworkUtils;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.swing.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.pxst.constants.BankCardConstant.*;
import static com.pxst.internalReports.constants.AccountListConstant.*;

/**
 * @author yangxy
 * @version 创建时间：2023年9月7日 下午4:36:08
 */
@Service
public class SysAvailableBankServiceImpl extends JoinServiceImpl<SysAvailableBankMapper, SysAvailableBankEntity> implements SysAvailableBankService {

    @Autowired
    private SysAvailableBankMapper sysAvailableBankMapper;
    @Autowired
    private SysAvailableBankLogMapper sysAvailableBankLogMapper;
    @Autowired
    private SysFoOrderMainMapper sysFoOrderMainMapper;
    @Autowired
    private SysBankCardFlowEntityMapper sysBankCardFlowEntityMapper;
    @Autowired
    private SysVpnEntityMapper sysVpnMapper;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private SysDabTokenCardMapper sysDabTokenCardMapper;
    @Autowired
    private SysBankCardMapper sysBankCardMapper;
    @Autowired
    private SysBankCardService sysBankCardService;
    @Resource
    private SysBankReceiveRecordEntityMapper sysBankReceiveRecordEntityMapper;
    @Autowired
    private RedisUtils redisUtils;

    @Override
    public ApiResp<PageResp<BankAccountListResp>> getBankAccountList(BankAccountListReq bankAccountListReq) {
        // 查询分页数据
        PageHelper.startPage(bankAccountListReq.getPage(), bankAccountListReq.getRp());
        Page<BankAccountListResp> page = (Page<BankAccountListResp>) sysAvailableBankMapper.getBankAccountList(bankAccountListReq);

        //获取小计数据
        Map<String, BigDecimal> subTotals = getSubTotals(page.getResult());

        //获取总计数据，如果总计数据小于100条则不查询，为小计数据
        Map<String, BigDecimal> totals = subTotals;
        if (page.getTotal() > 0 && page.getTotal() > 100) {
            // 获取总计数据
            totals = sysAvailableBankMapper.getTotals(bankAccountListReq);
        }

        return ApiResp.page(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), page.getResult(), subTotals, totals);
    }

    private Map<String, BigDecimal> getSubTotals(List<BankAccountListResp> result) {
        BigDecimal todayDP = new BigDecimal(0);
        BigDecimal todayPayout = new BigDecimal(0);
        BigDecimal balance = new BigDecimal(0);
        BigDecimal balanceXy = new BigDecimal(0);

        for (BankAccountListResp bankAccountListResp : result) {
            todayDP = todayDP.add(bankAccountListResp.getTotalDayCredit());
            todayPayout = todayPayout.add(bankAccountListResp.getTotalDayDebit());
            balance = balance.add(bankAccountListResp.getBalance());
            balanceXy = balanceXy.add(bankAccountListResp.getXyBalance());
        }
        Map<String, BigDecimal> subTotal = new HashMap<>();
        subTotal.put("orderAmount", todayDP);
        subTotal.put("requestAmount", todayPayout);
        subTotal.put("paidAmount", balance);
        subTotal.put("lossAmount", balanceXy);

        return subTotal;
    }

    @Override
    public ApiResp<SysBankReceiveRecordEntity> take(Long id) {
        //根据银行卡id查询银行卡账户表中的数据，判断该银行卡是否存在
        SysBankCardEntity sysBankCardEntity = sysBankCardMapper.selectById(id);
        //如果该银行卡不存在则返回错误信息
        if (ObjectUtils.isEmpty(sysBankCardEntity)) {
            return ApiResp.bussError("该银行卡不存在");
        }

        //根据银行卡id在银行卡账户领取卡片纪录表中查询是否有未归还的记录，如果有则说明该银行卡已被领取
        QueryWrapper<SysBankReceiveRecordEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("bank_card_id", id);
        queryWrapper.isNull("return_at");
        SysBankReceiveRecordEntity sysBankReceiveRecordEntity = sysBankReceiveRecordEntityMapper.selectOne(queryWrapper);
        //如果该银行卡已被领取则返回错误信息
        if (ObjectUtils.isNotEmpty(sysBankReceiveRecordEntity)) {
            return ApiResp.bussError("该银行卡已被领取");
        }

        //添加领取记录
        SysBankReceiveRecordEntity sysBankReceiveRecordEntity1 = new SysBankReceiveRecordEntity();
        sysBankReceiveRecordEntity1.setBankCardId(id);
        sysBankReceiveRecordEntity1.setTakenAt(new Date());
        //获取当前登录用户id
        sysBankReceiveRecordEntity1.setAdminId(SecurityFrameworkUtils.getLoginUserId());
        sysBankReceiveRecordEntityMapper.insert(sysBankReceiveRecordEntity1);

        return ApiResp.sucess(sysBankReceiveRecordEntity1);
    }

    @Override
    public ApiResp<SysBankReceiveRecordEntity> returnCard(Long id) {
        //根据银行卡id在银行卡账户领取卡片纪录表中查询是否有未归还的记录
        QueryWrapper<SysBankReceiveRecordEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("bank_card_id", id);
        queryWrapper.isNull("return_at");
        SysBankReceiveRecordEntity sysBankReceiveRecordEntity = sysBankReceiveRecordEntityMapper.selectOne(queryWrapper);
        //如果没有未归还的数据则返回错误信息
        if (ObjectUtils.isEmpty(sysBankReceiveRecordEntity)) {
            return ApiResp.bussError("该银行卡没有被领取");
        }

        //获取当前登录用户id
        Long adminId = SecurityFrameworkUtils.getLoginUserId();
        //判断当前登录用户是否是领取该银行卡的用户
        if (!sysBankReceiveRecordEntity.getAdminId().equals(adminId)) {
            return ApiResp.bussError("该银行卡不是当前用户领取的");
        }

        //领取记录中添加归还时间
        sysBankReceiveRecordEntity.setReturnAt(new Date());
        sysBankReceiveRecordEntityMapper.updateById(sysBankReceiveRecordEntity);

        return ApiResp.sucess(sysBankReceiveRecordEntity);
    }

    @Override
    public ApiResp<String> forceReturnCards(Long id) {
        //根据用户id在银行卡账户领取卡片纪录表中查询所有未归还的记录
        QueryWrapper<SysBankReceiveRecordEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("admin_id", id);
        queryWrapper.isNull("return_at");
        List<SysBankReceiveRecordEntity> sysBankReceiveRecordEntityList = sysBankReceiveRecordEntityMapper.selectList(queryWrapper);
        //修改所有未归还的记录的归还时间为当前时间
        for (SysBankReceiveRecordEntity sysBankReceiveRecordEntity : sysBankReceiveRecordEntityList) {
            sysBankReceiveRecordEntity.setUpdatedAt(new Date());
            sysBankReceiveRecordEntityMapper.updateById(sysBankReceiveRecordEntity);
        }

        return ApiResp.sucess();
    }

    @Override
    public ApiResp<List<Map<String, List<AccountListResp>>>> getAccountList(Integer type) {
        ArrayList<Integer> types = new ArrayList<>();
        int from = 0;
        int to = 0;
        //From Account
        if (ACCOUNT_LIST_1.contains(type)) {
            types.add(1);
            from = 1;
        } else if (ACCOUNT_LIST_2.contains(type)) {
            types.add(2);
            from = 2;
        } else if (ACCOUNT_LIST_3.contains(type)) {
            types.add(3);
            from = 3;
        } else if (ACCOUNT_LIST_4.contains(type)) {
            types.add(4);
            from = 4;
        }
        //To Account
        if (ACCOUNT_LIST_5.contains(type)) {
            types.add(2);
            to = 2;
        } else if (ACCOUNT_LIST_6.contains(type)) {
            types.add(3);
            to = 3;
        } else if (ACCOUNT_LIST_7.contains(type)) {
            types.add(4);
            to = 4;
        }
        List<Map<String, List<AccountListResp>>> maps = new ArrayList<>();
        for (int i = 0; i < 2; i++) {
            JoinLambdaWrapper<SysBankCardEntity> lambdaWrapper = new JoinLambdaWrapper<>(SysBankCardEntity.class);

            if (i == 0) {
                //第一次定义SysBankCardEntity的查询条件,from列表
                lambdaWrapper.in(SysBankCardEntity::getType, types)
                        .in(SysBankCardEntity::getStatus, STATUS_ACTIVE, STATUS_HOLD, STATUS_HOLD_SMS_FAILED)
                        .eq(SysBankCardEntity::getType, from);
            } else {
                //第二次定义SysBankCardEntity的查询条件,to列表
                lambdaWrapper.in(SysBankCardEntity::getType, types)
                        .in(SysBankCardEntity::getStatus, STATUS_ACTIVE, STATUS_HOLD, STATUS_HOLD_SMS_FAILED)
                        .eq(SysBankCardEntity::getType, to);
            }
            //SysBankCard表中要查的字段
            lambdaWrapper.selectAs((cd) -> {
                cd.addFunAlias(SysBankCardEntity::getId, AccountListResp::getBankCardId)
                        .add(SysBankCardEntity::getBankCardGroupId)
                        .add(SysBankCardEntity::getCurrency)
                        .add(SysBankCardEntity::getStatus)
                        .add(SysBankCardEntity::getMobileName)
                        .addFunAlias(SysBankCardEntity::getType, AccountListResp::getBankCardType)
                        .add(SysBankCardEntity::getDayDepositMax)
                        .add(SysBankCardEntity::getAccountCode)
                        .add(SysBankCardEntity::getDayStreamOutMax)
                        .add(SysBankCardEntity::getMonthStreamOutMax)
                        .add(SysBankCardEntity::getMonthThresholdMax);
            });

            //定义SysBankCardEntity关联的SysBankCardFlowEntity对象
            lambdaWrapper.leftJoin(SysBankCardFlowEntity.class, SysBankCardFlowEntity::getBankCardId, SysBankCardEntity::getId)
                    .selectAs((cd) -> {
                        cd.add(SysBankCardFlowEntity::getBalance)
                                .add(SysBankCardFlowEntity::getXyBalance)
                                .add("fo_freeze_amount+fx_freeze_amount+et_freeze_amount+tr_freeze_out_amount", "reservedBalance", false)
                                .add("balance-fo_freeze_amount+fx_freeze_amount+et_freeze_amount+tr_freeze_out_amount", "realBalance", false)
                                .add("day_stream_out_max-day_flow_out", "dailyRemainingFromLimit", false)
                                .add("day_stream_out_max-day_flow_in", "dailyRemainingToLimit", false)
                                .add("month_stream_out_max-month_flow_out", "monthlyRemainingFromLimit", false)
                                .add("month_stream_out_max-month_flow_in", "monthlyRemainingToLimit", false)
                                .add("month_threshold_max-month_success_in_count-month_freeze_success_in_count-month_success_out_count-month_freeze_success_out_count",
                                        "monthlyRemainingToLimit", false);
                    })
                    .end();
            //定义SysBankCardEntity关联的SysAvailableBankEntity对象
            lambdaWrapper.leftJoin(SysAvailableBankEntity.class, SysAvailableBankEntity::getId, SysBankCardEntity::getAvailableBankId)
                    .selectAs((cd) -> {
                        cd.add(SysAvailableBankEntity::getBankCode)
                                .add(SysAvailableBankEntity::getTrMax)
                                .add(SysAvailableBankEntity::getTrMin)
                                .add("CONCAT_WS('_', bank_name, RIGHT(bank_card_number,5))", "accountRemark", false)
                                .add("CASE WHEN (day_treshold > 0) THEN (day_treshold-day_success_in_count-day_freeze_success_in_count-day_success_out_count-day_freeze_success_out_count) else 0 end",
                                        "dRemainingNumberOfTimes", false);
                    })
                    .end();

            List<AccountListResp> accountListResp = sysBankCardService.joinList(lambdaWrapper, AccountListResp.class);
            Map<String, List<AccountListResp>> stringListMap = new HashMap<>();
            if (ObjectUtils.isNotEmpty(accountListResp)) {
                stringListMap.put(accountListResp.get(0).getBankCardTypeName(), accountListResp);
                maps.add(stringListMap);
            }
        }

        return ApiResp.sucess(maps);
    }

    /**
     * 银行卡下拉框信息
     *
     * @return
     */
    @Override
    public ApiResp<BankCardResp> getInfo() {
        JoinLambdaWrapper<SysBankCardEntity> jlw = new JoinLambdaWrapper<>(SysBankCardEntity.class);
        jlw.selectAs((cb) -> {
            cb.addFunAlias(SysBankCardEntity::getId, BankCardResp::getBankCardId)
                    .addFunAlias(SysBankCardEntity::getAvailableBankId, BankCardResp::getBankId)
                    .addFunAlias(SysBankCardEntity::getBankCardNumber, BankCardResp::getNumber)
                    .addFunAlias(SysBankCardEntity::getUserName, BankCardResp::getName)
                    .add(SysBankCardEntity::getCurrency)
                    .add(SysBankCardEntity::getAccountCode);
        });

        jlw.leftJoin(SysAvailableBankEntity.class, SysAvailableBankEntity::getId, SysBankCardEntity::getAvailableBankId)
                .select(SysAvailableBankEntity::getBankCode)
                .end();

        List<BankCardResp> bankCardResps = sysBankCardMapper.joinSelectList(jlw, BankCardResp.class);
        return ApiResp.sucess(bankCardResps);
    }

    /**
     * 银行卡详情
     *
     * @param id
     * @return
     */
    @Override
    public ApiResp<BankCardResp> getBank(Long id) {
        //1、根据id查出银行账户信息
        SysBankCardEntity systemBankCard = sysBankCardMapper.selectById(id);

        if (systemBankCard == null) {
            return ApiResp.bussError("无账户信息");
        }

        //2.拷贝属性
        BankCardAllResp bankCardAllVo = new BankCardAllResp();
        bankCardAllVo.setMaxBalance(systemBankCard.getDayDepositMax());
        bankCardAllVo.setIdentity(systemBankCard.getFoPin());
        bankCardAllVo.setYoutapPin(systemBankCard.getFoPin());
        BeanUtils.copyProperties(systemBankCard, bankCardAllVo);

        //3.通过systemBankCard中的bankid去查询system_bank表中数据
        SysAvailableBankEntity systemBank = sysAvailableBankMapper.selectById(systemBankCard.getAvailableBankId());

        //4.通过systemBankCard中的bankcardid去查询sys_bank_card_flow表中数据
        SysBankCardFlowEntity systemBankCardBill = sysBankCardFlowEntityMapper.selectOne(new LambdaQueryWrapper<SysBankCardFlowEntity>()
                .eq(SysBankCardFlowEntity::getBankCardId, id));

        if (systemBank != null) {
            bankCardAllVo.setHoldTime(getHoldTime(systemBank.getBankCode(), systemBankCard.getHoldAt()));
        }

        if (systemBank != null && systemBankCardBill != null) {
            //5.需要计算的数据
            bankCardAllVo.setDRemainingNumberOfTimes(systemBank.getDayTreshold() > 0 ? (int) (systemBank.getDayTreshold()
                    - systemBankCardBill.getDaySuccessInCount()
                    - systemBankCardBill.getDayFreezeSuccessInCount() - systemBankCardBill.getDaySuccessOutCount()
                    - systemBankCardBill.getDayFreezeSuccessOutCount() - systemBankCardBill.getDayUnknownVbs()) : 0);
        }

        if (systemBankCardBill != null) {
            //5.需要计算的数据
            bankCardAllVo.setEtHoldBalance(systemBankCardBill.getEtFreezeAmount());
            bankCardAllVo.setFiHoldBalance(systemBankCardBill.getFiFreezeAmount());
            bankCardAllVo.setFoHoldBalance(systemBankCardBill.getFoFreezeAmount());
            bankCardAllVo.setFxHoldBalance(systemBankCardBill.getFxFreezeAmount());
            bankCardAllVo.setTrInHoldBalance(systemBankCardBill.getTrFreezeInAmount());
            bankCardAllVo.setTrOutHoldBalance(systemBankCardBill.getTrFreezeOutAmount());

            BigDecimal d_i = systemBankCard.getDayStreamOutMax().subtract(systemBankCardBill.getDayFlowIn());
            BigDecimal d_o = systemBankCard.getDayStreamOutMax().subtract(systemBankCardBill.getDayFlowOut());
            BigDecimal m_i = systemBankCard.getMonthStreamOutMax().subtract(systemBankCardBill.getMonthFlowIn());
            BigDecimal m_o = systemBankCard.getMonthStreamOutMax().subtract(systemBankCardBill.getMonthFlowOut());
            bankCardAllVo.setDRemainingLimitI(d_i);
            bankCardAllVo.setDRemainingLimitO(d_o);
            bankCardAllVo.setMRemainingLimitI(m_i);
            bankCardAllVo.setDRemainingLimitO(m_o);
            bankCardAllVo.setDIWarning(systemBankCard.getDayStreamOutMax().multiply(BigDecimal.valueOf(0.05)).compareTo(d_i) >= 0);
            bankCardAllVo.setDOWarning(systemBankCard.getDayStreamOutMax().multiply(BigDecimal.valueOf(0.05)).compareTo(d_o) >= 0);
            bankCardAllVo.setMIWarning(systemBankCard.getMonthStreamOutMax().multiply(BigDecimal.valueOf(0.05)).compareTo(m_i) >= 0);
            bankCardAllVo.setMOWarning(systemBankCard.getMonthStreamOutMax().multiply(BigDecimal.valueOf(0.05)).compareTo(m_o) >= 0);

            long remainingNumberofTimes = systemBankCard.getMonthThresholdMax()
                    - systemBankCardBill.getMonthSuccessInCount()
                    - systemBankCardBill.getMonthSuccessOutCount()
                    - systemBankCardBill.getMonthFreezeSuccessInCount()
                    - systemBankCardBill.getMonthFreezeSuccessOutCount();
            bankCardAllVo.setRemainingNumberOfTimes(remainingNumberofTimes);

            bankCardAllVo.setTimesWarning(remainingNumberofTimes <= 5);

            BigDecimal remainingBalance = systemBankCard.getStatus() == 5 ? BigDecimal.valueOf(0.0) : systemBankCardBill.getBalance();
            bankCardAllVo.setRemainingBalance(remainingBalance);

            List<Integer> list = new ArrayList<>();
            list.add(BankCardConstant.TYPE_FO);
            list.add(BankCardConstant.TYPE_FX);
            bankCardAllVo.setBalanceWarning(list.contains(systemBankCard.getType())
                    && remainingBalance.compareTo(systemBankCard.getDayDepositMax().multiply(BigDecimal.valueOf(0.05))) <= 0);
            bankCardAllVo.setBalanceUpperWarning(systemBankCard.getType() == BankCardConstant.TYPE_FI
                    && remainingBalance.compareTo(systemBankCard.getDayDepositMax().multiply(BigDecimal.valueOf(0.95))) >= 0);

            BigDecimal reservedBalance = systemBankCardBill.getFoFreezeAmount().add(systemBankCardBill.getFxFreezeAmount())
                    .add(systemBankCardBill.getEtFreezeAmount()).add(systemBankCardBill.getTrFreezeOutAmount());
            bankCardAllVo.setRealBalance(systemBankCardBill.getBalance().subtract(reservedBalance));
        }

        //6.通过systemBankCard中的server_id去查询system_server_list表中数据
        SysVpnEntity sysVpnEntity = sysVpnMapper.selectById(systemBankCard.getVpnId());
        if (sysVpnEntity != null) {
            bankCardAllVo.setPreVPN100ID(null);
            bankCardAllVo.setVpnName(sysVpnEntity.getName());
        }

        Statement statement = new Statement();
        if (systemBankCard.getStatement() != null && !systemBankCard.getStatement().isEmpty()) {
            JSONObject jsonObject = new JSONObject(systemBankCard.getStatement());
            statement.setStatus(jsonObject.getInt("status", null));
            statement.setCount(jsonObject.getInt("count", null));
            statement.setHistoryStatus(jsonObject.getInt("historStatus", null));
            statement.setIsErrurl(jsonObject.getInt("isErrurl", null));
            statement.setLCount(jsonObject.getInt("lCount", null));
            statement.setManualPlay(jsonObject.getInt("manualPlay", null));
            statement.setPCount(jsonObject.getInt("pCount", null));
            bankCardAllVo.setStatement(statement);
        } else {
            bankCardAllVo.setStatement(statement);
        }

        //7.通过systemBankCard中的id去查询sys_dab_token_card表中数据
        List<SysDabTokenCard> systemDabTokenCards = sysDabTokenCardMapper.selectList(new LambdaQueryWrapper<SysDabTokenCard>()
                .eq(SysDabTokenCard::getBankCardId, systemBankCard.getId()));
        if (systemDabTokenCards != null) {
            bankCardAllVo.setIsDabTokenCard(systemDabTokenCards.size() > 0);
        }

        return ApiResp.sucess(bankCardAllVo);
    }

    @Override
    public ApiResp<List<AvailableBankListResp>> getAvailableBank() {
        return ApiResp.sucess(sysAvailableBankMapper.getBankSelectList());
    }

    private String getHoldTime(String code, Date holdAt) {

        //得到hold_time_limit
        Integer subCode = null;
        try {
            subCode = Integer.valueOf(sysConfigService.getSubCode(RedisContant.HOLDTIMELIMIT, code));
        } catch (Exception e) {
            subCode = 0;
        }

        //2.得到hold_time
        Long holdTime = null;
        // 将 holtAt 转换成秒数
        long time = holdAt.getTime() / 1000;
        // 计算要增加的秒数
        int secondsToAdd = subCode * 60;
        //增加秒数后的总秒数
        holdTime = time + secondsToAdd;

        //3.将hold_time经过计算得到分钟和秒数
        long minute = (holdTime % 86400 % 3600) / 60;
        long second = (holdTime % 86400 % 3600) % 60;

        //返回hold_time的数据
        if (minute < 1) {
            return "01:00";
        } else {
            return String.format("%02d:%02d", minute, second);
        }
    }

    /**
     * 银行-搜索
     *
     * @param bankSearchReq 银行搜索请求类
     * @return 银行列表
     */
    @Override
    public ApiResp<List<BankSearchResp>> getBankListByCondition(BankSearchReq bankSearchReq) {
        // 单表操作 对银行表sys_available_bank
        // select
        //      ab.bank_code,ab.bank_name,ab.currency,ab.fi_max,ab.fi_min,ab.fo_max,fo_min,ab.fx_max,ab.fx_min,ab.tr_max,ab.tr_min,ab.note(前缀备注?),ab.reserved_amount,status(1.可用 0.暂停 BS200)
        // from sys_available_bank as ab
        // where ab.currency = ?
        // 1.根据 币种currency 查询对应的银行列表
        /*LambdaQueryWrapper<SysAvailableBankEntity> lqw = new LambdaQueryWrapper<>();
        lqw.select(SysAvailableBankEntity.class, sys_available_bank ->
                        // 查询时排除以下字段(根据前端页面显示的数据排除)
                        !sys_available_bank.getColumn().equals("day_treshold")
                                // && !sys_available_bank.getColumn().equals("id")
                                && !sys_available_bank.getColumn().equals("meta")
                                && !sys_available_bank.getColumn().equals("is_captcha")
                                && !sys_available_bank.getColumn().equals("is_qr")
                                && !sys_available_bank.getColumn().equals("reserved_amount")) // ?
                // 查询条件 where currency = ?
                .eq(SysAvailableBankEntity::getCurrency, bankSearchReq.getCurrency());
        List<SysAvailableBankEntity> bankList = sysAvailableBankMapper.selectList(lqw);*/
        PageHelper.startPage(bankSearchReq.getPage(), bankSearchReq.getRp());
        // 1.根据 币种 查询对应的银行列表
        List<SysAvailableBankEntity> bankList = sysAvailableBankMapper.selectList(new LambdaQueryWrapper<SysAvailableBankEntity>().eq(SysAvailableBankEntity::getCurrency, bankSearchReq.getCurrency()));
        // 2. 封装返回结果
        List<BankSearchResp> collect = bankList.stream().map(bank -> {
            // 2.1 创建银行搜索返回类
            BankSearchResp bankSearchResp = new BankSearchResp();
            // 2.2 元素拷贝
            BeanUtils.copyProperties(bank, bankSearchResp);
            return bankSearchResp;
        }).collect(Collectors.toList());
        return ApiResp.sucess(collect);
    }

    /**
     * 银行-编辑 sys_available_bank表
     *
     * @param id            修改的银行id
     * @param bankUpdateReq 要修改银行对象的值
     * @return
     */
    @Override
    public ApiResp<Spring> updateBankById(Long id, BankUpdateReq bankUpdateReq) {
        /*// 1.根据id获取到需要修改的银行对象 修改操作查询到的对象不可能为空
        SysAvailableBankEntity bankEntity1 = sysAvailableBankMapper.selectById(id);
        System.out.println("根据id查询到需要修改的银行对象bankEntity = " + bankEntity1);
        // 2. 编辑时对象原本已经有数据，不用判断编辑输入的内容是否为空
        // 3. 将原数据删除，再插入编辑后的数据
        // 3.1 删除原数据
        sysAvailableBankMapper.deleteById(id);
        // 3.2
        // SysAvailableBankEntity bankEntity = new SysAvailableBankEntity();
        System.out.println("修改的bankEntity对象的值为： " + sysAvailableBankEntity);
        sysAvailableBankMapper.insert(sysAvailableBankEntity);
        return ApiResp.sucess();*/
       /* // 1. 修改操作查询到的对象不可能为空  编辑时对象原本已经有数据，不用判断编辑输入的内容是否为空
        LambdaUpdateWrapper<SysAvailableBankEntity> lqw = new LambdaUpdateWrapper<>();
        // 2. 将原数据修改为前端页面传入的值
        lqw.set(SysAvailableBankEntity::getCurrency, sysAvailableBankEntity.getCurrency()) // 货币
                .set(SysAvailableBankEntity::getStatus, sysAvailableBankEntity.getStatus()) // 状态
                .set(SysAvailableBankEntity::getTrMax, sysAvailableBankEntity.getTrMax()) // 最大内转额
                .set(SysAvailableBankEntity::getTrMin, sysAvailableBankEntity.getTrMin()) // 最小内转额
                .set(SysAvailableBankEntity::getFiMax, sysAvailableBankEntity.getFiMax()) // 最大充值额
                .set(SysAvailableBankEntity::getFiMin, sysAvailableBankEntity.getFiMin()) // 最小充值额
                .set(SysAvailableBankEntity::getFoMax, sysAvailableBankEntity.getFoMax()) // 最大代付额
                .set(SysAvailableBankEntity::getFoMin, sysAvailableBankEntity.getFoMin()) // 最小代付额
                .set(SysAvailableBankEntity::getFxMax, sysAvailableBankEntity.getFxMax()) // 最大下发额
                .set(SysAvailableBankEntity::getFxMin, sysAvailableBankEntity.getFxMin()) // 最小下发额
                .set(SysAvailableBankEntity::getNote, sysAvailableBankEntity.getNote()) // 前缀备注???
                // 要修改的银行的id  条件 where id = ?
                .eq(SysAvailableBankEntity::getId, id);
        sysAvailableBankMapper.update(sysAvailableBankEntity, lqw);
        // 直接根据实体类进行修改 ???
        // sysAvailableBankMapper.updateById(sysAvailableBankEntity);*/
        // 1. 将需要修改的值拷贝到银行对象中
        SysAvailableBankEntity sysAvailableBankEntity = new SysAvailableBankEntity();
        BeanUtils.copyProperties(bankUpdateReq, sysAvailableBankEntity);
        // 2. 修改银行id 为id 的银行对象
        sysAvailableBankMapper.update(sysAvailableBankEntity, new LambdaQueryWrapper<SysAvailableBankEntity>().eq(SysAvailableBankEntity::getId, id));
        return ApiResp.sucess();
    }

    /**
     * 银行-新增 sys_available_bank表
     *
     * @param sysAvailableBankEntity 新增的银行对象信息
     * @return
     */
    @Override
    public ApiResp<String> create(SysAvailableBankEntity sysAvailableBankEntity) {
        // 1. 判断新增的字段(没有默认值的字段)是否为空
        if (StringUtils.isBlank(sysAvailableBankEntity.getBankCode()) || sysAvailableBankEntity.getBankCode() == null) {
            return ApiResp.paramError("银行码不能为空");
            //  throw new ValidationException("银行码不能为空");
        }
        if (StringUtils.isBlank(sysAvailableBankEntity.getBankName()) || sysAvailableBankEntity.getBankName() == null) {
            return ApiResp.paramError("银行名称不能为空");
            //throw new ValidationException("银行名称不能为空");
        }
        if (StringUtils.isBlank(sysAvailableBankEntity.getCurrency()) || sysAvailableBankEntity.getCurrency() == null) {
            return ApiResp.paramError("货币不能为空");
            //throw new ValidationException("币种不能为空");
        }
        // System.out.println("新增的银行对象的属性: " + sysAvailableBankEntity);
        // 银行名称,银行码 是否可以相同? ,新增的银行状态是否可以为停用状态?
        // 插入一条银行记录 单表操作?
        sysAvailableBankMapper.insert(sysAvailableBankEntity);
        return ApiResp.sucess();
    }

    /**
     * 获取银行列表信息
     *
     * @param basePageRsp 分页参数
     * @return
     */
    @Override
    public ApiResp<PageResp<BankSearchResp>> getBankInfoList(BasePageRsp basePageRsp) {
        // 1. 分页
        PageHelper.startPage(basePageRsp.getPage(), basePageRsp.getRp());
        // 2. 查询全部数据
        List<BankSearchResp> bankSearchRespList = sysAvailableBankMapper.selectAll();
        return ApiResp.page(basePageRsp.getPage(), basePageRsp.getRp(), bankSearchRespList.size(), bankSearchRespList);
    }

    /**
     * 银行-详情
     *
     * @param bankDetailReq 银行详情请求类
     * @return 该银行对应的log表 sys_available_bank_log
     */
    @Override
    public ApiResp<List<BankDetailResp>> getBankById(BankDetailReq bankDetailReq) {
        // 1. 分页
        PageHelper.startPage(bankDetailReq.getPage(), bankDetailReq.getRp());
        // 2. 根据bankId查询对应的log信息
        List<SysAvailableBankLogEntity> bankLogList = sysAvailableBankLogMapper.selectList(new LambdaQueryWrapper<SysAvailableBankLogEntity>().eq(SysAvailableBankLogEntity::getAvailableBankId, bankDetailReq.getId()));
        if (bankLogList == null || bankLogList.size() == 0) {
            return ApiResp.bussError("无对应的log信息");
        }
        /*System.out.println("bankLogList = " + bankLogList);
        bankLogList.forEach(bankLog -> {
            System.out.print("bankLog = " + bankLog);
            System.out.println();
        });*/
        // 3. 封装结果对象
        List<BankDetailResp> collect = bankLogList.stream().map(bank -> {
            // 3.1元素拷贝
            BankDetailResp bankDetailResp = new BankDetailResp();
            BeanUtils.copyProperties(bank, bankDetailResp);
            return bankDetailResp;
        }).collect(Collectors.toList());
        return ApiResp.sucess(collect);
    }

    /**
     * 银行-详情-搜索
     *
     * @param bankDetailSearchReq 搜索（条件查询）请求类
     * @return 返回（根据条件）查询到的数据集合
     */
    @Override
    public ApiResp<List<BankDetailResp>> getBankLogByCondition(BankDetailSearchReq bankDetailSearchReq) {
        // 分页
        PageHelper.startPage(bankDetailSearchReq.getPage(), bankDetailSearchReq.getRp());
        LambdaQueryWrapper<SysAvailableBankLogEntity> lqw = new LambdaQueryWrapper<>();
        // 1. 如果传入了type 根据type 对 content 进行模糊查询
        lqw.like(StringUtils.isNotBlank(bankDetailSearchReq.getType()), SysAvailableBankLogEntity::getContent, bankDetailSearchReq.getType())
                // 2. 如果传入了adminName 查询指定更新人 adminName
                .eq(StringUtils.isNotBlank(bankDetailSearchReq.getAdminName()), SysAvailableBankLogEntity::getUpdater, bankDetailSearchReq.getAdminName())
                // 3. 如果传入了时间 创建时间在给定的时间范围内
                .between(bankDetailSearchReq.getStartDate() != null && bankDetailSearchReq.getEndDate() != null, SysAvailableBankLogEntity::getCreatedAt, bankDetailSearchReq.getStartDate(), bankDetailSearchReq.getEndDate());
        // 根据指定条件查询到对应的结果集
        List<SysAvailableBankLogEntity> bankLogEntityList = sysAvailableBankLogMapper.selectList(lqw);
        return ApiResp.sucess(bankLogEntityList);
    }
}
